package com.dragon.modules.yuegou.service.impl.merchant;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dragon.common.exception.DragonException;
import com.dragon.common.web.PageRequest;
import com.dragon.modules.media.workbook.validate.ValidateException;
import com.dragon.modules.media.workbook.validate.ValidateResult;
import com.dragon.modules.yuegou.entity.merchant.MerchantEntity;
import com.dragon.modules.yuegou.entity.merchant.MerchantSalesEntity;
import com.dragon.modules.yuegou.entity.merchant.MerchantSalesMonthEntity;
import com.dragon.modules.yuegou.enums.code.DistrictCode;
import com.dragon.modules.yuegou.enums.code.MerchantCode;
import com.dragon.modules.yuegou.enums.code.WalletCode;
import com.dragon.modules.yuegou.enums.merchant.MerchantSalesMonthSource;
import com.dragon.modules.yuegou.enums.merchant.MerchantSalesSource;
import com.dragon.modules.yuegou.excel.merchant.MerchantSalesConfigWorkbook;
import com.dragon.modules.yuegou.excel.merchant.MerchantSalesTemplateWorkbook;
import com.dragon.modules.yuegou.excel.merchant.MerchantSalesWorkbook;
import com.dragon.modules.yuegou.mapper.merchant.MerchantSalesMapper;
import com.dragon.modules.yuegou.model.merchant.Merchant;
import com.dragon.modules.yuegou.model.merchant.MerchantSales;
import com.dragon.modules.yuegou.model.merchant.MerchantSalesMonth;
import com.dragon.modules.yuegou.model.merchant.SalesReportModel;
import com.dragon.modules.yuegou.model.merchant.SalesReportQuery;
import com.dragon.modules.yuegou.model.system.Document;
import com.dragon.modules.yuegou.query.merchant.MerchantQuery;
import com.dragon.modules.yuegou.query.merchant.MerchantSalesMonthQuery;
import com.dragon.modules.yuegou.query.merchant.MerchantSalesQuery;
import com.dragon.modules.yuegou.query.merchant.SalesQuery;
import com.dragon.modules.yuegou.service.merchant.MerchantSalesMonthService;
import com.dragon.modules.yuegou.service.merchant.MerchantSalesService;
import com.dragon.modules.yuegou.service.merchant.MerchantService;
import com.dragon.modules.yuegou.service.system.DocumentService;
import com.dragon.modules.yuegou.utils.DateUtil;
import com.dragon.modules.yuegou.utils.PageToResultUtils;
import com.dragon.modules.yuegou.web.Check;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 商铺销售额 服务实现
 *
 * @author pbuilder generated
 * @date 2019-05-20 10:37:56
 * @version 2.0
 */
@Slf4j
@Service("merMerchantSalesService")
public class MerchantSalesServiceImpl
		extends ServiceImpl<MerchantSalesMapper, MerchantSalesEntity>
		implements MerchantSalesService {

	private static final String IMPORT_FILE = "导入配置数据";

	private static final String DATE_FORRMAT = "yyyy-MM-dd";

	private static final String DATE_FORRMAT_TAIL= " 00:00:00";

	@Autowired
	private MerchantSalesMapper merchantSalesMapper;

	@Autowired
	private MerchantSalesMonthService merchantSalesMonthService;

	@Autowired
	private DocumentService documentService;

	@Autowired
	private MerchantService merchantService;



	@Override
	public IPage<MerchantSales> searchMerchantList(PageRequest page, SalesQuery query){
		Check.notNull(query.getBusdId(), DistrictCode.DISTRICT_NOTNULL.getMessage());
		IPage<MerchantSales> salesPage = merchantSalesMapper.searchMerchantList(PageToResultUtils.resultToPage(page), query);
		if(salesPage != null && CollectionUtils.isNotEmpty(salesPage.getRecords())){
			for(MerchantSales merchantSales : salesPage.getRecords()){
				//计算客单价
				if (merchantSales.getVolume() >0){
					merchantSales.setSinglePrice(merchantSales.getSales().divide(new BigDecimal(merchantSales.getVolume()), 2, BigDecimal.ROUND_HALF_UP));
				}else {
					merchantSales.setSinglePrice(BigDecimal.ZERO);
				}
				//计算坪效
				if(merchantSales.getMerchantAcreage()!=null){
					merchantSales.setEffect(merchantSales.getSales().divide(merchantSales.getMerchantAcreage(), 2, BigDecimal.ROUND_HALF_UP));
				}

				this.setRentSales(query,merchantSales);

			}
		}
		return salesPage;
	}

	private void setRentSales(SalesQuery query,MerchantSales merchantSales){
		//计算租金管理费和租售比
		MerchantSales sales = merchantSalesMonthService.countRentalSales(query.getBusdId(), merchantSales.getStatisticalTime());
		if(sales.getRental()!=null) {
			merchantSales.setRental(sales.getRental());
			if (merchantSales.getSales().compareTo(BigDecimal.ZERO) > 0) {
				merchantSales.setRentSales(merchantSales.getSales().divide(sales.getRental(), 2, BigDecimal.ROUND_HALF_UP));
			}
		}
	}

	@Override
	public void saveMerchantSales(MerchantSales merchantSales){
		Check.notNull(merchantSales.getMerchantId(),"商户id不能为空");
		Check.notNull(merchantSales.getStatisticalTime(),"日期不能为空");
		Check.notNull(merchantSales.getVolume(),"成交量不能为空");
		Check.positive(merchantSales.getVolume(),"成交量必须为正整数");
		Check.digits(merchantSales.getVolume(),10,0,"成交量必须为正整数");
		Check.notNull(merchantSales.getSales(),"成交额不能为空");
		Check.positive(merchantSales.getSales(),"成交额必须为正数");
		Check.digits(merchantSales.getSales(),10,2,"成交额格式不正确");
		MerchantSalesQuery query = new MerchantSalesQuery();
		query.setMerchantId(merchantSales.getMerchantId());
		query.setStatisticalTime(merchantSales.getStatisticalTime());
		MerchantSalesEntity sales = getOne(query.toQueryWrapper());
		if(StringUtils.isEmpty(sales.getId())) {
			merchantSales.setSource(MerchantSalesSource.MINIAPP);
			save(merchantSales);
		}else{
			throw new DragonException(MerchantCode.SALES_EXISTS);
		}
	}

	@Override
	public Document exportMerchantSales(SalesQuery query){
		Check.notNull(query.getBusdId(), DistrictCode.DISTRICT_NOTNULL.getMessage());
		List<MerchantSales> list = merchantSalesMapper.searchMerchantList(query);
		MerchantSalesWorkbook salesWorkbook = new MerchantSalesWorkbook();
		List<MerchantSalesWorkbook.MerchantSalesRow> salesList = new ArrayList<>();
		if(CollectionUtils.isNotEmpty(list)) {
			for (MerchantSales merchantSales : list){
				MerchantSalesWorkbook.MerchantSalesRow salesRow = getMerchantSalesRow(merchantSales,query.getBusdId());
				salesList.add(salesRow);
			}
		}
		log.debug("导出数据=={}"+salesList.size());
		salesWorkbook.setSalesList(salesList);
		return documentService.generateExcel("销售数据表.xlsx", salesWorkbook);
	}

	private MerchantSalesWorkbook.MerchantSalesRow getMerchantSalesRow(MerchantSales merchantSales,String busdId){
		MerchantSalesWorkbook.MerchantSalesRow salesRow = new MerchantSalesWorkbook.MerchantSalesRow();
		salesRow.setTypeName(merchantSales.getTypeName());
		salesRow.setMerchantName(merchantSales.getMerchantName());
		salesRow.setMerchantCode(merchantSales.getMerchantCode());
		salesRow.setSales(merchantSales.getSales());
		DateTimeFormatter df = DateTimeFormatter.ofPattern(DATE_FORRMAT);
		String sTime = df.format(merchantSales.getStatisticalTime());
		salesRow.setStaticalTime(sTime);
		salesRow.setVolume(merchantSales.getVolume());
		//计算坪效
		if(merchantSales.getMerchantAcreage()!=null){
			merchantSales.setEffect(merchantSales.getSales().divide(merchantSales.getMerchantAcreage(), 2, BigDecimal.ROUND_HALF_UP));
		}
		salesRow.setEffect(merchantSales.getEffect());
		//计算租金管理费和租售比
		MerchantSales sales = merchantSalesMonthService.countRentalSales(busdId, merchantSales.getStatisticalTime());
		if(sales.getRental()!=null) {
			merchantSales.setRental(sales.getRental());
			if (merchantSales.getSales().compareTo(BigDecimal.ZERO) > 0) {
				merchantSales.setRentSales(merchantSales.getSales().divide(sales.getRental(), 2, BigDecimal.ROUND_HALF_UP));
			}
		}
		salesRow.setRental(merchantSales.getRental());
		salesRow.setRentSales(merchantSales.getRentSales());
		//计算客单价
		if (merchantSales.getVolume() >0){
			merchantSales.setSinglePrice(merchantSales.getSales().divide(new BigDecimal(merchantSales.getVolume()), 2, BigDecimal.ROUND_HALF_UP));
		}else {
			merchantSales.setSinglePrice(BigDecimal.ZERO);
		}
		salesRow.setSinglePrice(merchantSales.getSinglePrice());
		salesRow.setMerchantAcreage(merchantSales.getMerchantAcreage());
		return salesRow;
	}


	@Override
	public Document exportSalesConfig(String busdId){
		Check.notNull(busdId, DistrictCode.DISTRICT_NOTNULL.getMessage());
		List<MerchantSalesMonth> list = merchantSalesMonthService.findList(busdId);
		MerchantSalesConfigWorkbook salesWorkbook = new MerchantSalesConfigWorkbook();
		List<MerchantSalesConfigWorkbook.SalesConfigRow> salesList = new ArrayList<>();
		if(CollectionUtils.isNotEmpty(list)) {
			for (MerchantSalesMonth merchantSales : list){
				MerchantSalesConfigWorkbook.SalesConfigRow salesRow = new MerchantSalesConfigWorkbook.SalesConfigRow();
				salesRow.setMerchantName(merchantSales.getMerchantName());
				salesRow.setMerchantCode(merchantSales.getMerchantCode());
				salesRow.setSales(merchantSales.getSalesBudget());
				salesRow.setRentalFee(merchantSales.getRentalManageFee());
				salesRow.setMonth(merchantSales.getMonthStr());
				salesList.add(salesRow);
			}
		}
		salesWorkbook.setSalesList(salesList);
		return documentService.generateExcel("配置数据表.xlsx", salesWorkbook);
	}

	@Override
	public Document getSalesTemplate(String busdId){
		MerchantSalesTemplateWorkbook salesTemplateWorkbook = new MerchantSalesTemplateWorkbook();
		return documentService.generateExcel("销售模板表.xlsx", salesTemplateWorkbook);
	}

	@Override
	public Document getConfigTemplate(String busdId){
		MerchantSalesConfigWorkbook salesConfigWorkbook = new MerchantSalesConfigWorkbook();
		return documentService.generateExcel("配置模板表.xlsx", salesConfigWorkbook);
	}

	@Override
	@Transactional
	public void importMerchantSales(String busdId, String fileId){
		Check.notNull(busdId, DistrictCode.DISTRICT_NOTNULL.getMessage());
		MerchantSalesTemplateWorkbook salesTemplateWorkbook = documentService.readExcel(fileId, MerchantSalesTemplateWorkbook.class);
		Map<String, String> merchantNameRepeatMap = new HashMap<>();//用于判断商户重复
		List<MerchantSales> list = new ArrayList<>();
		if(CollectionUtils.isNotEmpty(salesTemplateWorkbook.getSalesList())){
			for (int i=0; i<salesTemplateWorkbook.getSalesList().size(); i++) {
				MerchantSalesTemplateWorkbook.SalesRow salesRow = salesTemplateWorkbook.getSalesList().get(i);
				if(Objects.isNull(salesRow.getSales()) ||salesRow.getSales().compareTo(BigDecimal.ZERO) < 0){
					log.debug("导入销售数据,第s%行销售额不能为负数或空",(i+1));
					throw new DragonException(MerchantCode.SALES_IS_NULL.getCode(),String.format(MerchantCode.SALES_IS_NULL.getMessage(),i+1));
				}
				if(Objects.isNull(salesRow.getVolume())||salesRow.getVolume() < 0){
					log.debug("导入销售数据,第s%行成交量不能为负数或空",(i+1));
					throw new DragonException(MerchantCode.VOLUME_IS_NULL.getCode(),String.format(MerchantCode.VOLUME_IS_NULL.getMessage(),i+1));
				}
				MerchantQuery merchantQuery = new MerchantQuery();
				merchantQuery.setDel(false);
				merchantQuery.setBusdId(busdId);
				merchantQuery.setMerchantCode(salesRow.getMerchantCode());
				List<MerchantEntity> merchantList = merchantService.list(merchantQuery.toQueryWrapper());
				setMerchantSales(salesRow,merchantList,i,busdId,merchantNameRepeatMap,list);
			}
			batchMerchantSales(list);
		}else {
			throw new DragonException(WalletCode.EXCEL_SALES_DATA_NULL);
		}
	}

	private void setMerchantSales(MerchantSalesTemplateWorkbook.SalesRow salesRow,List<MerchantEntity> merchantList,int i,String busdId,Map<String, String> merchantNameRepeatMap,List<MerchantSales> list){
		Merchant merchant = new Merchant();
		String merchantId = "";
		String merchantName = "";
		if(merchantList != null && merchantList.size() > 1){
			log.debug("导入销售数据,第s%行商户铺位号出现重复，请至商户管理修改商户的铺位号",(i+1));
			throw new DragonException(MerchantCode.BERTH_NUMBER_REPEAT.getCode(),String.format(MerchantCode.BERTH_NUMBER_REPEAT.getMessage(),i+1));

		}else if (null != merchantList && merchantList.size() == 1) {
			merchant = new Merchant(merchantList.get(0));
		}
		if (merchant != null) {
			merchantId = merchant.getId();
			merchantName = merchant.getMerchantName();
		} else {
			log.debug("导入销售数据,第s%行商户不存在",(i+1));
			throw new DragonException(MerchantCode.MERCHANT_IS_NULL.getCode(),String.format(MerchantCode.MERCHANT_IS_NULL.getMessage(),i+1));

		}
		MerchantSales merchantSales = new MerchantSales();
		merchantSales.setBusdId(busdId);
		merchantSales.setMerchantId(merchantId);
		merchantSales.setMerchantName(merchantName);
		merchantSales.setSales(salesRow.getSales());
		merchantSales.setVolume(salesRow.getVolume());
		DateTimeFormatter dfQuery = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		String sTime = salesRow.getStaticalTime() + DATE_FORRMAT_TAIL;
		merchantSales.setStatisticalTime(LocalDateTime.parse(sTime, dfQuery));
		merchantSales.setSource(MerchantSalesSource.CRM);
		//较验商户重复
		String repeatKey = salesRow.getMerchantName();
		String value = merchantNameRepeatMap.get(repeatKey);
		if (null == value) {
			list.add(merchantSales);
			merchantNameRepeatMap.put(repeatKey, "1");
		} else {
			log.debug("导入销售数据,第s%行商户存在重复",(i+1));
			throw new DragonException(MerchantCode.MERCHANT_IS_NULL.getCode(),String.format(MerchantCode.MERCHANT_IS_NULL.getMessage(),i+1));

		}
	}

	private void batchMerchantSales(List<MerchantSales> list){
		//插入销售数据表
		for (int i = 0; i < list.size(); i++) {
			MerchantSales vo = list.get(i);
			//删除重复数据
			MerchantSalesQuery query = new MerchantSalesQuery();
			DateTimeFormatter df = DateTimeFormatter.ofPattern(DATE_FORRMAT);
			DateTimeFormatter dfQuery = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
			String month = df.format(vo.getStatisticalTime()) + DATE_FORRMAT_TAIL;
			query.setStatisticalTime(LocalDateTime.parse(month, dfQuery));
			query.setBusdId(vo.getBusdId());
			query.setMerchantId(vo.getMerchantId());
			List<MerchantSalesEntity> salesList = list(query.toQueryWrapper());
			if(CollectionUtils.isNotEmpty(salesList)) {
				remove(query.toQueryWrapper());
			}
			save(vo);
		}
	}

	@Override
	@Transactional
	public void importSalesConfig(String busdId, String fileId){
		Check.notNull(busdId, DistrictCode.DISTRICT_NOTNULL.getMessage());

		List<ValidateResult> errors = new ArrayList<>();
		MerchantSalesConfigWorkbook salesTemplateWorkbook = documentService.readExcel(fileId, MerchantSalesConfigWorkbook.class);
		Map<String, String> merchantNameRepeatMap = new HashMap<>();//用于判断商户和月份重复
		List<MerchantSalesMonth> list = new ArrayList<>();
		if(CollectionUtils.isNotEmpty(salesTemplateWorkbook.getSalesList())){
			for (int i=0; i<salesTemplateWorkbook.getSalesList().size(); i++) {
				MerchantSalesConfigWorkbook.SalesConfigRow salesRow = salesTemplateWorkbook.getSalesList().get(i);
				forSalesConfigRow(salesRow,errors,i,busdId,merchantNameRepeatMap,list);
			}
			batchSalesConfig(list);
		}else {
			throw new DragonException(WalletCode.EXCEL_DATA_NULL);
		}
		if(!errors.isEmpty()){
			throw new ValidateException(salesTemplateWorkbook, errors);
		}
	}

	private void forSalesConfigRow(MerchantSalesConfigWorkbook.SalesConfigRow salesRow,List<ValidateResult> errors,int i,String busdId,Map<String, String> merchantNameRepeatMap,List<MerchantSalesMonth> list){
		ValidateResult result = null;
		if(Objects.isNull(salesRow.getSales())||salesRow.getSales().compareTo(BigDecimal.ZERO) < 0){
			result = new ValidateResult(IMPORT_FILE, "销售预算", i+1, 1, "不能为负数或空");
			errors.add(result);
			return;
		}
		if(Objects.isNull(salesRow.getRentalFee())||salesRow.getRentalFee().compareTo(BigDecimal.ZERO) < 0){
			result = new ValidateResult(IMPORT_FILE, "租金及管理费", i+1, 1, "不能为负数或空");
			errors.add(result);
			return;
		}
		MerchantQuery merchantQuery = new MerchantQuery();
		merchantQuery.setDel(false);
		merchantQuery.setMerchantCode(salesRow.getMerchantCode());
		merchantQuery.setBusdId(busdId);
		List<MerchantEntity> merchantList = merchantService.list(merchantQuery.toQueryWrapper());
		Merchant merchant = new Merchant();
		String merchantId = "";
		if(merchantList != null && merchantList.size() > 1){
			result = new ValidateResult(IMPORT_FILE, "商户铺位号", i+1, 1, "出现重复，请至商户管理修改商户的铺位号");
			errors.add(result);
			return;
		}else if (null != merchantList && merchantList.size() == 1) {
			merchant = new Merchant(merchantList.get(0));
		}
		if (merchant != null) {
			merchantId = merchant.getId();
		} else {
			result = new ValidateResult(IMPORT_FILE, "商户", i+1, 1, "不存在");
			errors.add(result);
			return;
		}
		MerchantSalesMonth merchantSales = new MerchantSalesMonth();
		merchantSales.setBusdId(busdId);
		merchantSales.setMerchantId(merchantId);
		merchantSales.setSalesBudget(salesRow.getSales());
		merchantSales.setRentalManageFee(salesRow.getRentalFee());
		Integer year = Integer.parseInt(salesRow.getMonth().substring(0,4));
		Integer month = Integer.parseInt(salesRow.getMonth().substring(5,7));
		merchantSales.setMonth(LocalDate.of(year,month,1));
		merchantSales.setDel(false);
		merchantSales.setStatisticalTime(LocalDateTime.now());
		merchantSales.setSource(MerchantSalesMonthSource.CRM);
		//较验商户和月份重复
		String repeatKey = salesRow.getMerchantName() + salesRow.getMonth();
		String value = merchantNameRepeatMap.get(repeatKey);
		if (null == value) {
			list.add(merchantSales);
			merchantNameRepeatMap.put(repeatKey, "1");
		} else {
			result = new ValidateResult(IMPORT_FILE, "商户和月份", i+1, 1, "存在重复");
			errors.add(result);
		}
	}

	private void batchSalesConfig(List<MerchantSalesMonth> list){
		for (int i = 0; i < list.size(); i++) {
			MerchantSalesMonth vo = list.get(i);
			//删除重复数据
			MerchantSalesMonthQuery query = new MerchantSalesMonthQuery();
			query.setBusdId(vo.getBusdId());
			query.setMerchantId(vo.getMerchantId());
			DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM");
			DateTimeFormatter dfQuery = DateTimeFormatter.ofPattern(DATE_FORRMAT);
			String month = df.format(vo.getStatisticalTime()) + "-01";
			query.setMonth(LocalDate.parse(month, dfQuery));
			query.setDel(false);
			query.setBusdId(vo.getBusdId());
			List<MerchantSalesMonthEntity> monthList = merchantSalesMonthService.list(query.toQueryWrapper());
			if(CollectionUtils.isNotEmpty(monthList)) {
				MerchantSalesMonth merchantSalesMonth = new MerchantSalesMonth();
				merchantSalesMonth.setId(monthList.get(0).getId());
				merchantSalesMonth.setDel(true);
				merchantSalesMonthService.updateById(merchantSalesMonth);
			}
			//插入销售数据表
			merchantSalesMonthService.save(vo);
		}
	}

	@Override
	public void editSales(String id, BigDecimal sales, Integer volume){
		Check.notNull(id, "id不能为空");
		Check.notNull(sales, "销售额不能为空");
		Check.positive(sales, "销售额必须是正数");
		Check.digits(sales, 10, 2, "销售额格式不正确");
		Check.notNull(volume, "成交量不能为空");
		Check.positive(volume, "成交量必须是正数");
		Check.digits(volume, 10, 0, "成交量格式不正确");
		MerchantSales merchantSales = new MerchantSales();
		merchantSales.setId(id);
		merchantSales.setSales(sales);
		merchantSales.setVolume(volume);
		updateById(merchantSales);
	}


	@Override
	public SalesReportModel getSalesOfDayByBusd( SalesReportQuery reportQuery) {

		getReportQuery(reportQuery);
		SalesReportModel salesReportModel = merchantSalesMapper.getSalesOfDayByBusd(reportQuery);
		//计算客单价
		setCommonProperties(salesReportModel);

		getSequentialReportQuery(reportQuery);
		SalesReportModel sequentialSalesReportModel = merchantSalesMapper.getSalesOfDayByBusd(reportQuery);
		//计算客单价
		setCommonProperties(sequentialSalesReportModel);

		//计算环比
		sequential( salesReportModel,  sequentialSalesReportModel);
		salesReportModel.setSales(salesReportModel.getSales().divide(new BigDecimal(10000),2,BigDecimal.ROUND_HALF_UP));
		return salesReportModel;
	}


	@Override
	public IPage<SalesReportModel> getSalesOfDayByBtType(PageRequest page, SalesReportQuery reportQuery) {

		getReportQuery(reportQuery);
		IPage<SalesReportModel> salesPage = merchantSalesMapper.getSalesOfDayByBtType(PageToResultUtils.resultToPage(page), reportQuery);

		if(null != salesPage && CollectionUtils.isNotEmpty(salesPage.getRecords())){
			for(SalesReportModel salesReportModel : salesPage.getRecords()){
				setCommonProperties(salesReportModel);
			}
		}

		return salesPage;
	}

	@Override
	public IPage<SalesReportModel> getSalesOfDayByMerchant(PageRequest page, SalesReportQuery reportQuery) {
		getReportQuery(reportQuery);
		IPage<SalesReportModel> salesPage = merchantSalesMapper.getSalesOfDayByMerchant(PageToResultUtils.resultToPage(page), reportQuery);

		if(null != salesPage && CollectionUtils.isNotEmpty(salesPage.getRecords())){
			for(SalesReportModel salesReportModel : salesPage.getRecords()){
				setCommonProperties(salesReportModel);
			}
		}
		return salesPage;
	}

	@Override
	public SalesReportModel getSalesOfDayByBtTypeForDay(SalesReportQuery reportQuery) {
		getReportQuery(reportQuery);
		List<Map<String,Object>> list = merchantSalesMapper.getSalesOfDayByBtTypeForDay(reportQuery);

		return returnReportModel(list);
	}

	@Override
	public SalesReportModel getSalesOfDayByMerchantForDay(SalesReportQuery reportQuery) {
		getReportQuery(reportQuery);
		List<Map<String,Object>> list = merchantSalesMapper.getSalesOfDayByMerchantForDay(reportQuery);
		return returnReportModel(list);
	}

	private SalesReportModel returnReportModel(List<Map<String,Object>> list){
		SalesReportModel salesReportModel = new SalesReportModel();
		String[] reportKey = new String[list.size()];
		BigDecimal[] reportValue = new BigDecimal[list.size()];
		BigDecimal[] reportUnitPrice = new BigDecimal[list.size()];

		for (int i = 0 ; i < list.size(); i ++) {
			Map<String, Object> map = list.get(i);
			reportKey[i] = (String) map.get("statisticalTime");

			BigDecimal sales = (BigDecimal) map.get("sales");
			BigDecimal volume = (BigDecimal) map.get("volume");

			if (volume.compareTo(BigDecimal.ZERO) >0){
				reportUnitPrice[i] = (sales.divide(volume, 2, BigDecimal.ROUND_HALF_UP));
			}else {
				reportUnitPrice[i]  = BigDecimal.ZERO;
			}
			reportValue[i] = sales;
		}
		salesReportModel.setReportKey(reportKey);
		salesReportModel.setReportValue(reportValue);
		salesReportModel.setReportUnitPrice(reportUnitPrice);

		return salesReportModel;
	}

	private void setCommonProperties(SalesReportModel salesReportModel) {
		//计算客单价
		if (salesReportModel.getVolume() >0){
			salesReportModel.setUnitPrice(salesReportModel.getSales().divide(new BigDecimal(salesReportModel.getVolume()), 2, BigDecimal.ROUND_HALF_UP));
		}else {
			salesReportModel.setUnitPrice(BigDecimal.ZERO);
		}
		//计算坪效
		if(salesReportModel.getMerchantAcreage()!=null){
			salesReportModel.setEffect(salesReportModel.getSales().divide(salesReportModel.getMerchantAcreage(), 2, BigDecimal.ROUND_HALF_UP));
		} else {
			salesReportModel.setEffect(BigDecimal.ZERO);
		}

		//计算复购率
		if (null != salesReportModel.getReBuyNum() && salesReportModel.getReBuyNum().compareTo(BigDecimal.ZERO) > 0) {
			salesReportModel.setReBuyPercent(salesReportModel.getReBuyNum().divide(salesReportModel.getBuyerNum(),1,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)));
		} else {
			salesReportModel.setReBuyPercent(BigDecimal.ZERO);
		}
	}



	private void getReportQuery(SalesReportQuery reportQuery){
		if (null != reportQuery.getPlusDay() && reportQuery.getPlusDay() > 0) {
			LocalDateTime now = LocalDateTime.now();
			LocalDateTime oldDay = now.minusDays(reportQuery.getPlusDay());
			LocalDateTime todayStart = LocalDateTime.of(oldDay.toLocalDate(), LocalTime.MIN);//设置开始日期的零点

			LocalDateTime yesterday = now.minusDays(1);
			LocalDateTime todayEnd = LocalDateTime.of(yesterday.toLocalDate(), LocalTime.MAX);//当天零点

			reportQuery.setStartDay(DateUtil.formatStandardDateTime(todayStart));
			reportQuery.setEndDay(DateUtil.formatStandardDateTime(todayEnd));
		} else {
			String startDay = reportQuery.getStartDay();
			String endDay = reportQuery.getEndDay();
			reportQuery.setStartDay(startDay + DATE_FORRMAT_TAIL);
			reportQuery.setEndDay(endDay + " 23:59:59");
		}
	}


	private void getSequentialReportQuery(SalesReportQuery reportQuery){

		LocalDateTime startDay = DateUtil.parseDate(reportQuery.getStartDay());
		LocalDateTime endDay = DateUtil.parseDate(reportQuery.getEndDay());

		Duration between = Duration.between(startDay, endDay);
		LocalDateTime sequentialDay = startDay.minusDays(between.toDays() + 1);

		reportQuery.setStartDay(DateUtil.formatStandardDateTime(sequentialDay));
		reportQuery.setEndDay(DateUtil.formatStandardDateTime(startDay));

	}

	@Override
	public SalesReportModel getSalesOfMonthByBusd(SalesReportQuery reportQuery) {

		SalesReportModel salesReportModel = merchantSalesMapper.getSalesOfMonthByBusd(reportQuery);
		//计算客单价
		setCommonProperties(salesReportModel);

		String seachMonth = reportQuery.getSeachMonth() + "-01";
		LocalDate startMonth = DateUtil.parseLocalDate(seachMonth,DATE_FORRMAT);
		LocalDate minusMonths = startMonth.minusMonths(1);
		seachMonth = DateUtil.formatStandardDateForPattern(minusMonths, "yyyy-MM");
		reportQuery.setSeachMonth(seachMonth);

		SalesReportModel sequentialSalesReportModel = merchantSalesMapper.getSalesOfMonthByBusd(reportQuery);
		//计算客单价
		setCommonProperties(sequentialSalesReportModel);

		//计算环比
		sequential( salesReportModel,  sequentialSalesReportModel);
		salesReportModel.setSales(salesReportModel.getSales().divide(new BigDecimal(10000),2,BigDecimal.ROUND_HALF_UP));
		return salesReportModel;
	}

	private void sequential(SalesReportModel salesReportModel, SalesReportModel sequentialSalesReportModel) {
		//计算客单价
		setCommonProperties(sequentialSalesReportModel);

		//计算环比
		BigDecimal sequentialVolume = BigDecimal.ZERO;
		if (new BigDecimal(salesReportModel.getVolume()).compareTo(sequentialVolume) > 0) {
			sequentialVolume = new BigDecimal(salesReportModel.getVolume()).subtract(new BigDecimal(sequentialSalesReportModel.getVolume())).divide(new BigDecimal(sequentialSalesReportModel.getVolume()), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
		}

		BigDecimal sequentialSales = BigDecimal.ZERO;
		if (sequentialSalesReportModel.getSales().compareTo(BigDecimal.ZERO) > 0 && salesReportModel.getSales().compareTo(sequentialSales) > 0) {
			sequentialSales = salesReportModel.getSales().subtract(sequentialSalesReportModel.getSales()).divide(sequentialSalesReportModel.getSales(), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
		}
		BigDecimal sequentialUnitPrice = BigDecimal.ZERO;
		if (sequentialSalesReportModel.getUnitPrice().compareTo(BigDecimal.ZERO) > 0 && salesReportModel.getUnitPrice().compareTo(sequentialUnitPrice) > 0 ) {
			sequentialUnitPrice = salesReportModel.getUnitPrice().subtract(sequentialSalesReportModel.getUnitPrice()).divide(sequentialSalesReportModel.getUnitPrice(), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
		}
		BigDecimal sequentialEffect = BigDecimal.ZERO;
		if (sequentialSalesReportModel.getEffect().compareTo(BigDecimal.ZERO) > 0 && salesReportModel.getEffect().compareTo(sequentialEffect) > 0 ) {
			sequentialEffect = salesReportModel.getEffect().subtract(sequentialSalesReportModel.getEffect()).divide(sequentialSalesReportModel.getEffect(), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
		}
		salesReportModel.setSequentialVolume(sequentialVolume);
		salesReportModel.setSequentialSales(sequentialSales);
		salesReportModel.setSequentialUnitPrice(sequentialUnitPrice);
		salesReportModel.setSequentialEffect(sequentialEffect);
	}

	@Override
	public IPage<SalesReportModel> getSalesOfMonthByBtType(PageRequest page, SalesReportQuery reportQuery) {

		IPage<SalesReportModel> salesPage = merchantSalesMapper.getSalesOfMonthByBtType(PageToResultUtils.resultToPage(page), reportQuery);

		if(null != salesPage && CollectionUtils.isNotEmpty(salesPage.getRecords())){
			for(SalesReportModel salesReportModel : salesPage.getRecords()){
				setCommonProperties(salesReportModel);
			}
		}

		return salesPage;
	}

	@Override
	public IPage<SalesReportModel> getSalesOfMonthByMerchant(PageRequest page, SalesReportQuery reportQuery) {

		IPage<SalesReportModel> salesPage = merchantSalesMapper.getSalesOfMonthByMerchant(PageToResultUtils.resultToPage(page), reportQuery);

		if(null != salesPage && CollectionUtils.isNotEmpty(salesPage.getRecords())){
			for(SalesReportModel salesReportModel : salesPage.getRecords()){
				setCommonProperties(salesReportModel);
			}
		}
		return salesPage;
	}
}